package com.kedacom.demo.healthcheck;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 健康检查
 * @author luocanfeng
 * @date 2016年9月2日
 */
@Service
public class HealthCheck extends ApplicationObjectSupport {

	public static final String STATUS_OK = "200";
	public static final String STATUS_ERR = "500";

	@Value("${app.name}")
	private String appName;
	@Value("${app.version}")
	private String appVersion;
	@Resource(name = "healthCheckItems")
	private List<HealthCheckItem> healthCheckItems = new ArrayList<HealthCheckItem>(); // 健康检查项目

	private HealthCheckResult result;

	private Logger logger = LoggerFactory.getLogger(getClass());

	public HealthCheckResult check() {
		if (result == null) {
			doCheck();
		}
		return result;
	}

	@Scheduled(cron = "${cron.expression.health.check}")
	public void run() {
		doCheck();
	}

	public HealthCheckResult doCheck() {
		logger.debug("health check start");
		HealthCheckResult result = new HealthCheckResult(getAppVersion(), STATUS_OK);
		for (HealthCheckItem item : healthCheckItems) {
			boolean check = item.check();
			result.getResults()
					.add(new HealthCheckItemResult(item.getName(), item.getType(), check ? STATUS_OK : STATUS_ERR));
			if (!check) {
				result.setStatus(STATUS_ERR);
			}
		}
		this.result = result;
		try {
			ObjectMapper mapper = new ObjectMapper();
			logger.debug("health check end, result is {}", mapper.writeValueAsString(result));
		} catch (JsonProcessingException e) {
		}
		return result;
	}

	public String getAppName() {
		return appName;
	}

	public void setAppName(String appName) {
		this.appName = appName;
	}

	public String getAppVersion() {
		return appVersion;
	}

	public void setAppVersion(String appVersion) {
		this.appVersion = appVersion;
	}

	public List<HealthCheckItem> getHealthCheckItems() {
		return healthCheckItems;
	}

	public void setHealthCheckItems(List<HealthCheckItem> healthCheckItems) {
		this.healthCheckItems = healthCheckItems;
	}

}
